#include <iostream>
#include <vector>
#include <unistd.h>
#include <time.h>
#include "BlockQueue.hpp"

class Task
{
public:
    Task(int num1=1, int num2=2)
    :_num1(num1)
    ,_num2(num2)
    {}
    int Add()
    {
        return _num1+_num2;
    }
    int GetNum1()
    {
        return _num1;
    }
    int GetNum2()
    {
        return _num2;
    }
private:
    int _num1;
    int _num2;
};
//生产线程，生产数据和任务向阻塞队列中写
void* ProductRun(void* rags)
{
    BlockQueue<Task>* bq = static_cast<BlockQueue<Task>*>(rags); 
    while(true)
    {
        int num1 = rand()%10+1;//随机数范围在1~10之间
        usleep(1000);//休眠原因是使得两次生成的随机数不一样
        int num2 = rand()%10+1;
        Task task(num1, num2);
        bq->Enqueue(task);
        sleep(2);
    }

    return nullptr;
} 
//消费线程，读取数据执行任务
void* ConsumeRun(void* rags)
{
    BlockQueue<Task>* bq = static_cast<BlockQueue<Task>*>(rags); 
    Task task(1,2);
    while(true)
    {
        int num = 0;
        bq->Pop(task);
        std::cout << task.GetNum1() << " + " << task.GetNum2() << " = " << task.Add() <<std::endl;
    }

    return nullptr;
}
int main()
{
    srand(time(NULL));
    BlockQueue<Task> bq;
    std::vector<pthread_t> threads;
    for(int i=0; i<5; ++i)
    {
        pthread_t PthreadId;
        pthread_create(&PthreadId, nullptr, ProductRun, (void*)&bq);
        threads.push_back(PthreadId);
    }
    for(int i=0; i<4; ++i)
    {
        pthread_t CThreadId;
        pthread_create(&CThreadId, nullptr, ConsumeRun, (void*)&bq);
        threads.push_back(CThreadId);
    }
    for(auto tmp:threads)
    {
        pthread_join(tmp, nullptr);
    }

    return 0;
}



/*//生产线程，生产数据和任务向阻塞队列中写
void* ProductRun(void* rags)
{
    BlockQueue<int>* bq = static_cast<BlockQueue<int>*>(rags); 
    while(true)
    {
        int num1 = rand()%10+1;//随机数范围在1~10之间
        std::cout << "write: " << num1 <<std::endl;
        bq->Enqueue(num1);
        sleep(2);
    }
    return nullptr;
} 
//消费线程，读取数据执行任务
void* ConsumeRun(void* rags)
{
    BlockQueue<int>* bq = static_cast<BlockQueue<int>*>(rags); 
    while(true)
    {
        int num = 0;
        bq->Pop(num);
        std::cout << "read: " << num <<std::endl;
    }
    return nullptr;
}
int main()
{
    srand(time(NULL));
    BlockQueue<int> bq;
    pthread_t CThreadId;
    pthread_t PthreadId;
    pthread_create(&PthreadId, nullptr, ProductRun, (void*)&bq);
    pthread_create(&CThreadId, nullptr, ConsumeRun, (void*)&bq);

    pthread_join(CThreadId, nullptr);
    pthread_join(PthreadId, nullptr);

    return 0;
}*/


/*//定义全局锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
//定义全局变量
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void* ThreadRun(void* args)
{
    char* name = (char*)args;
    while(true)
    {
        //加锁
        pthread_mutex_lock(&mutex); 
        //线程到指定的条件变量下去等待
        pthread_cond_wait(&cond, &mutex);

        std::cout << name << std::endl;
        usleep(10000);//1万微秒 
        //解锁
        pthread_mutex_unlock(&mutex); 
    }
    return nullptr;
}
int main()
{
    std::vector<pthread_t> threads;
    std::vector<char*> free;

    for(int i=0; i<5; ++i)
    {
        pthread_t id;
        char* name = new char[50];
        snprintf(name, 50, "thread_%d", i);
        free.push_back(name);

        pthread_create(&id, nullptr, ThreadRun, (void*)name);
        threads.push_back(id);
    }
    //主线程唤醒指定条件变量下的线程(一次只唤醒一个线程)
    while(true)
    {
        pthread_cond_signal(&cond);
    }
    //主线程等待新线程
    for(int i=0; i<5; ++i)
    {
        pthread_join(threads[i], nullptr);
        delete[] free[i];
    }
    //释放锁
    pthread_mutex_destroy(&mutex);

    return 0;
}*/
